from fastapi import Request, Depends
from sqlalchemy.ext.asyncio import AsyncSession
from typing import List
from config.constant import CommonConstant
from exceptions.exception import ServiceException
from module_admin.entity.vo.common_vo import CrudResponseModel
from module_admin.service.dict_service import DictDataService
from module_admin.dao.llm_dao import LlmDao
from module_admin.entity.vo.llm_vo import DeleteLlmModel, LlmModel, LlmPageQueryModel
from utils.common_util import CamelCaseUtil
from utils.excel_util import ExcelUtil
from config.get_db import get_db


class LlmService:
    """
    大模型配置模块服务层
    """

    @classmethod
    async def get_llm_list_services(
        cls,
        query_db: AsyncSession,
        query_object: LlmPageQueryModel,
        is_page: bool = False,
    ):
        """
        获取大模型配置列表信息service

        :param query_db: orm对象
        :param query_object: 查询参数对象
        :param is_page: 是否开启分页
        :return: 大模型配置列表信息对象
        """
        llm_list_result = await LlmDao.get_llm_list(query_db, query_object, is_page)

        return llm_list_result

    @classmethod
    async def add_llm_services(cls, query_db: AsyncSession, page_object: LlmModel):
        """
        新增大模型配置信息service

        :param query_db: orm对象
        :param page_object: 新增大模型配置对象
        :return: 新增大模型配置校验结果
        """
        try:
            await LlmDao.add_llm_dao(query_db, page_object)
            await query_db.commit()
            return CrudResponseModel(is_success=True, message="新增成功")
        except Exception as e:
            await query_db.rollback()
            raise e

    @classmethod
    async def edit_llm_services(cls, query_db: AsyncSession, page_object: LlmModel):
        """
        编辑大模型配置信息service

        :param query_db: orm对象
        :param page_object: 编辑大模型配置对象
        :return: 编辑大模型配置校验结果
        """
        edit_llm = page_object.model_dump(exclude_unset=True, exclude={})
        llm_info = await cls.llm_detail_services(query_db, page_object.id)
        if llm_info.id:
            try:
                await LlmDao.edit_llm_dao(query_db, edit_llm)
                await query_db.commit()
                return CrudResponseModel(is_success=True, message="更新成功")
            except Exception as e:
                await query_db.rollback()
                raise e
        else:
            raise ServiceException(message="大模型配置不存在")

    @classmethod
    async def delete_llm_services(
        cls, query_db: AsyncSession, page_object: DeleteLlmModel
    ):
        """
        删除大模型配置信息service

        :param query_db: orm对象
        :param page_object: 删除大模型配置对象
        :return: 删除大模型配置校验结果
        """
        if page_object.ids:
            id_list = page_object.ids.split(",")
            try:
                for id in id_list:
                    await LlmDao.delete_llm_dao(query_db, LlmModel(id=id))
                await query_db.commit()
                return CrudResponseModel(is_success=True, message="删除成功")
            except Exception as e:
                await query_db.rollback()
                raise e
        else:
            raise ServiceException(message="传入ID为空")

    @classmethod
    async def llm_detail_services(cls, query_db: AsyncSession, id: int):
        """
        获取大模型配置详细信息service

        :param query_db: orm对象
        :param id: ID
        :return: ID对应的信息
        """
        llm = await LlmDao.get_llm_detail_by_id(query_db, id=id)
        if llm:
            result = LlmModel(**CamelCaseUtil.transform_result(llm))
        else:
            result = LlmModel(**dict())

        return result

    @staticmethod
    async def export_llm_list_services(request: Request, llm_list: List):
        """
        导出大模型配置信息service

        :param llm_list: 大模型配置信息列表
        :return: 大模型配置信息对应excel的二进制数据
        """
        # 创建一个映射字典，将英文键映射到中文键
        mapping_dict = {
            "id": "ID",
            "scenario": "场景代码",
            "modelName": "模型名称",
            "modelDesc": "模型描述",
            "apiKey": "API_KEY",
            "baseUrl": "BASE_URL",
            "systemPrompt": "系统提示词",
            "used": "是否启用",
        }
        sys_yes_no_list = (
            await DictDataService.query_dict_data_list_from_cache_services(
                request.app.state.redis, dict_type="sys_yes_no"
            )
        )
        sys_yes_no_option = [
            dict(label=item.get("dictLabel"), value=item.get("dictValue"))
            for item in sys_yes_no_list
        ]
        sys_yes_no_option_dict = {item.get("value"): item for item in sys_yes_no_option}
        for item in llm_list:
            if str(item.get("used")) in sys_yes_no_option_dict.keys():
                item["used"] = sys_yes_no_option_dict.get(str(item.get("used"))).get(
                    "label"
                )
        binary_data = ExcelUtil.export_list2excel(llm_list, mapping_dict)

        return binary_data
